#pragma once
#include "Sem.hpp"
#include "Mutex.hpp"
#include <vector>
#include <iostream>
static const int gcap = 5;
using namespace SemMoudle;
using namespace MutexMoudle;
template <class T>
class RingQueue
{
public:
    RingQueue(const int cap = gcap)
        : _cap(cap), _p_stap(0), _c_stap(0), _p_blank(cap), _c_data(0), _rq(cap)
    {
    }
    // 生产者往表里生产数据
    void Equeue(const T &date)
    {
        // 申请信号量
        _p_blank.P();
        {
            Mutexground aslock(_p_mutex);
            _rq[_p_stap] = date;
            _p_stap++;
            _p_stap %= _cap;
        }
        _c_data.V();
    }
    // 消费者往表里获得数据
    void pop(T *date)
    {
        _c_data.P();
        {
            Mutexground aslock(_c_mutex);
            *date = _rq[_c_stap];
            _c_stap++;
            _c_stap %= _cap;
        }
        _p_blank.V();
    }

private:
    std::vector<T> _rq;
    int _cap;
    // 生产者
    Sem _p_blank;
    int _p_stap;
    // 消费者
    Sem _c_data;
    int _c_stap;
    // 维护多生产多消费关系
    Mutex _c_mutex;
    Mutex _p_mutex;
};